package main

import (
	"crypto/rsa"
	"fmt"
	"os"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
)

func authenticate(c *gin.Context) {
	// 跳过 /login 路由
	if c.Request.URL.Path == "/login" {
		c.Next()
		return
	}

	tokenStr, nil := c.Cookie("token")

	publicKey, err := loadPublicKey("public.pem")
	// 验证 JWT
	token, err := validateJWT(tokenStr, publicKey)
	if err != nil {
		c.JSON(401, gin.H{"error": "验证 JWT 失败"})
		c.Abort()
		return
	}

	claims, ok := token.Claims.(jwt.MapClaims)
	fmt.Println(claims, ok)

	c.Next()
}

func protected(c *gin.Context) {
	c.JSON(200, gin.H{"message": "Protected resource accessed successfully"})
}

func loadPublicKey(filepath string) (*rsa.PublicKey, error) {
	// 读取公钥文件
	keyData, err := os.ReadFile(filepath)
	if err != nil {
		return nil, err
	}

	// 解析 PEM 格式的公钥
	publicKey, err := jwt.ParseRSAPublicKeyFromPEM(keyData)
	if err != nil {
		return nil, err
	}

	return publicKey, nil
}

// 验证 JWT Token
func validateJWT(tokenStr string, publicKey *rsa.PublicKey) (*jwt.Token, error) {
	// 解析和验证 JWT Token
	token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
		// 确保 Token 使用的是 RS256 签名方法
		if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
			return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
		}

		// 返回公钥用于签名验证
		return publicKey, nil
	})
	if err != nil {
		return nil, err
	}

	// 验证 Token 的有效性
	if !token.Valid {
		return nil, fmt.Errorf("invalid token")
	}

	return token, nil
}

func main() {
	r := gin.Default()
	r.Use(authenticate)

	r.GET("/protected", protected)
	r.Run(":8081")
}
